package com.fakeDYChat.common.websocket;

import cn.hutool.core.net.url.UrlBuilder;
import cn.hutool.extra.servlet.ServletUtil;
import com.fakeDYChat.common.common.utils.NettyUtil;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpRequest;
import org.apache.commons.lang3.StringUtils;

import java.net.InetSocketAddress;
import java.util.Optional;

public class HttpHeadersHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        if (msg instanceof HttpRequest) {
            HttpRequest request = (HttpRequest) msg;
            UrlBuilder urlBuilder = UrlBuilder.ofHttp(request.uri());
            // 获取token参数并设置到ctx上下文
            String token = getToken(urlBuilder);
            NettyUtil.setAttr(ctx.channel(), NettyUtil.TOKEN, token);
            // 获取ip并设置到ctx上下文
            String ip = getIp(ctx, request);
            NettyUtil.setAttr(ctx.channel(), NettyUtil.IP, ip);
            // 移除后面拼接的token
            request.setUri(urlBuilder.getPath().toString());
            //移除该handler
            ctx.pipeline().remove(this);
            //放行并使其调用下一个handler
            ctx.fireChannelRead(request);
        } else {
            //放行并使其调用下一个handler
            ctx.fireChannelRead(msg);
        }
    }

    /**
     * 获取ip
     *
     * @param ctx     netty通道
     * @param request http请求
     * @return java.lang.String
     * @author Tang
     * @date 2024/1/4 20:41
     **/
    private String getIp(ChannelHandlerContext ctx, HttpRequest request) {
        HttpHeaders headers = request.headers();
        String ip = headers.get("X-Real-IP");
        if (StringUtils.isEmpty(ip)) {//如果没经过nginx，就直接获取远端地址
            InetSocketAddress address = (InetSocketAddress) ctx.channel().remoteAddress();
            ip = address.getAddress().getHostAddress();
        }
        return ip;
    }

    /**
     * 获取token
     *
     * @param urlBuilder url路径解析器
     * @return java.lang.String
     * @author Tang
     * @date 2024/1/4 20:41
     **/
    private String getToken(UrlBuilder urlBuilder) {
        return Optional.ofNullable(urlBuilder.getQuery())
                .map(k -> k.get("token"))
                .map(CharSequence::toString)
                .orElse("");
    }
}